package com.example.ccj.b.c.draw.voice;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;

import com.example.ccj.u.LogUtils;
import com.example.ccj.u.NumberUtils;
import com.example.ccj.u.SizeUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 扩散の环
 */
public class CircleRoundView extends View implements VisualizerHelper.OnVisualizerEnergyCallBack {
    float energy = 0;
    //当频谱能量大于该值时绘制
    private int energyEnable = 300;
    //半径
    private int minRadius = SizeUtils.dp2px(30);
    //透明衰减触发位置
    private float transparencyFallOffTrigger = 0.3f;
    //扩散速度
    private int speed = 10;
    //中心点X轴坐标
    private int centerX;
    //中心点Y轴坐标
    private int centerY;
    //圆环绘制区域
    private RectF rectF = new RectF();
    //每个圆环信息储存集合
    private List<CircleRoundViewBean> list = new ArrayList<>();
    private Random random = new Random();
    private Paint paint = new Paint();
    OnTouchEventListener onTouchEventListener;

    public CircleRoundView(Context context) {
        super(context);
        init();
    }

    public CircleRoundView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CircleRoundView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void setTransparencyFallOffTrigger(float transparencyFallOffTrigger) {
        this.transparencyFallOffTrigger = transparencyFallOffTrigger;
    }

    boolean isStartRes = false;


    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                LogUtils.d("onDraw: 按下");
                //首次按下或者已经抬起来了再次按下返回按下回调
                if (onTouchEventListener != null && !isStartRes) {
                    onTouchEventListener.down();
                    isStartRes = true;
                }
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
//                logUtil.d("抬起");
                if (onTouchEventListener != null) {
                    onTouchEventListener.up();
                    isStartRes = false;
                }
                break;
        }
        return true;
    }

    public void setOnTouchEvent3(OnTouchEventListener onTouchEventListener){
        this.onTouchEventListener = onTouchEventListener;
    }


    @Override
    public void setWaveData(byte[] data, float totalEnergy) {
        energy = totalEnergy;
        if (energy > energyEnable) {
            CircleRoundViewBean circleRoundViewBean = new CircleRoundViewBean();
            circleRoundViewBean.radius = (int) (minRadius + energy / 1000);
            circleRoundViewBean.red = NumberUtils.randomInt(random, (int) (AppConstant.RED * (energy / 10000f)), AppConstant.RED);
            circleRoundViewBean.green = NumberUtils.randomInt(random, (int) (AppConstant.GREEN * (energy / 10000f)), AppConstant.GREEN);
            circleRoundViewBean.blue = NumberUtils.randomInt(random, (int) (AppConstant.BLUE * (energy / 10000f)), AppConstant.BLUE);
            list.add(circleRoundViewBean);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        centerX = getWidth() / 2;
        centerY = getHeight() / 2;
    }

    private void init() {
        paint.setColor(AppConstant.COLOR);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setAntiAlias(true);
    }

    public int red;
    public int green;
    public int blue;

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        red = NumberUtils.randomInt(random, (int) (AppConstant.RED * (energy / 10000f)), AppConstant.RED);
        green = NumberUtils.randomInt(random, (int) (AppConstant.GREEN * (energy / 10000f)), AppConstant.GREEN);
        blue = NumberUtils.randomInt(random, (int) (AppConstant.BLUE * (energy / 10000f)), AppConstant.BLUE);


        for (int i = 0; i < list.size(); i++) {
            if (rectF == null) return;
            rectF.left = centerX - list.get(i).radius;
            rectF.right = centerX + list.get(i).radius;
            rectF.top = centerY - list.get(i).radius;
            rectF.bottom = centerY + list.get(i).radius;
            paint.setColor(Color.argb(getAlpha(i, list.get(i)), list.get(i).red, list.get(i).green, list.get(i).blue));
            canvas.drawArc(rectF, 0, 360, false, paint);
        }

        for (int i = 0; i < 3; i++) {
            if (rectF == null) return;
            rectF.left = centerX-50-i*5;
            rectF.right = centerX+50+i*5;
            rectF.top = centerY-50-i*5;
            rectF.bottom = centerY+50+i*5;
            paint.setColor(Color.GREEN);
            canvas.drawArc(rectF, 0, 360, false, paint);
        }

        if (!list.isEmpty()) {
            spread();
        }

        if (!list.isEmpty() || isStartRes) {
            invalidate();
        }
    }

    private int getAlpha(int i, CircleRoundViewBean circleRoundViewBean) {
        float radiusPercentValue = (float) (circleRoundViewBean.radius * 1.0 / Math.max(getWidth() / 2, getHeight() / 2));
        float indexPercentValue = list.isEmpty() ? 1.0f : i / (list.size() * 1.0f);

        if (radiusPercentValue < indexPercentValue && radiusPercentValue < transparencyFallOffTrigger) {
            return AppConstant.ALPHA;
        }
        return (int) (AppConstant.ALPHA - (AppConstant.ALPHA * indexPercentValue));
    }

    private void spread() {
        removeOutOfBorder();
        for (int i = 0; i < list.size(); i++) {
            list.get(i).radius += speed;
        }
    }

    private void removeOutOfBorder() {
        if (!list.isEmpty()) {
            if (list.get(0).radius > Math.max(getWidth(), getHeight())) {
                list.remove(0);
            }
        }

    }

}
